package com.tennis.tennisreservation.service.impl;

import com.tennis.tennisreservation.entity.Order;
import com.tennis.tennisreservation.entity.Coupon;
import com.tennis.tennisreservation.repository.OrderRepository;
import com.tennis.tennisreservation.service.CouponService;
import com.tennis.tennisreservation.service.OrderService;
import com.tennis.tennisreservation.repository.UserRepository;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.support.JpaRepositoryImplementation;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import jakarta.persistence.criteria.Predicate;

/**
 * 订单服务实现类
 */
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderRepository orderRepository;
    
    @Autowired
    private CouponService couponService;
    
    @Autowired
    private UserRepository userRepository;

    @Override
    @Transactional
    public Order createOrder(Order order) {
        // 设置创建时间和更新时间
        LocalDateTime now = LocalDateTime.now();
        order.setCreateTime(now);
        order.setUpdateTime(now);
        
        // 设置默认支付状态
        if (order.getPayStatus() == null) {
            order.setPayStatus("unpaid");
        }
        
        return orderRepository.save(order);
    }

    @Override
    @Transactional
    public Order updateOrder(Order order) {
        Order existingOrder = orderRepository.findById(order.getId())
                .orElseThrow(() -> new RuntimeException("订单不存在"));
        
        // 保留原创建时间
        order.setCreateTime(existingOrder.getCreateTime());
        // 更新时间为当前时间
        order.setUpdateTime(LocalDateTime.now());
        
        return orderRepository.save(order);
    }

    @Override
    @Transactional
    public boolean cancelOrder(Long id) {
        Optional<Order> orderOpt = orderRepository.findById(id);
        if (orderOpt.isPresent()) {
            Order order = orderOpt.get();
            // 将订单状态设置为"cancelled"
            order.setStatus("cancelled");
            order.setUpdateTime(LocalDateTime.now());
            orderRepository.save(order);
            return true;
        }
        return false;
    }

    @Override
    public Order getOrderById(Long id) {
        return orderRepository.findById(id).orElse(null);
    }

    @Override
    public List<Order> getOrdersByUserId(Long userId) {
        return orderRepository.findByUserId(userId);
    }

    @Override
    public Map<String, Object> getOrderList(int page, int size, Long userId, String keyword, 
                                            String payStatus, String status, LocalDateTime startDate, LocalDateTime endDate) {
        // 创建分页和排序
        Pageable pageable = PageRequest.of(page - 1, size, Sort.by(Sort.Direction.DESC, "createTime"));
        
        // 构建结果Map
        Map<String, Object> result = new HashMap<>();
        Page<Order> pageResult;
        
        // 根据条件进行查询
        if (userId != null && StringUtils.hasText(keyword)) {
            // 用户ID + 关键词查询
            pageResult = orderRepository.findByUserIdAndKeyword(userId, keyword, pageable);
        } else if (userId != null) {
            // 仅用户ID查询
            pageResult = orderRepository.findByUserId(userId, pageable);
        } else {
            // 创建简单的条件查询，避免使用复杂的Specification
            if (StringUtils.hasText(payStatus) && StringUtils.hasText(status)) {
                // 按支付状态和订单状态查询
                List<Order> orders = orderRepository.findByPayStatusAndStatus(payStatus, status);
                result.put("list", orders);
                result.put("total", (long) orders.size());
                return result;
            } else if (StringUtils.hasText(payStatus)) {
                // 按支付状态查询
                List<Order> orders = orderRepository.findByPayStatus(payStatus);
                
                // 如果status有值，基于支付状态筛选的结果再过滤订单状态
                if (StringUtils.hasText(status)) {
                    orders = orders.stream()
                            .filter(order -> status.equals(order.getStatus()))
                            .collect(Collectors.toList());
                }
                
                result.put("list", orders);
                result.put("total", (long) orders.size());
                return result;
            } else if (StringUtils.hasText(status)) {
                // 按订单状态查询
                List<Order> orders = orderRepository.findByStatus(status);
                result.put("list", orders);
                result.put("total", (long) orders.size());
                return result;
            } else if (startDate != null && endDate != null) {
                // 按日期范围查询
                List<Order> orders = orderRepository.findByCreateTimeBetween(startDate, endDate);
                
                // 如果status有值，过滤特定状态的订单
                if (StringUtils.hasText(status)) {
                    orders = orders.stream()
                            .filter(order -> status.equals(order.getStatus()))
                            .collect(Collectors.toList());
                }
                
                result.put("list", orders);
                result.put("total", (long) orders.size());
                return result;
            } else {
                // 查询所有订单并分页
                pageResult = orderRepository.findAll(pageable);
                
                // 如果status有值，过滤特定状态的订单
                if (StringUtils.hasText(status)) {
                    List<Order> filteredOrders = pageResult.getContent().stream()
                            .filter(order -> status.equals(order.getStatus()))
                            .collect(Collectors.toList());
                    
                    result.put("list", filteredOrders);
                    // 计算大致的总数
                    double ratio = pageResult.getContent().isEmpty() ? 0 : 
                        (double) filteredOrders.size() / pageResult.getContent().size();
                    long estimatedTotal = (long) (pageResult.getTotalElements() * ratio);
                    result.put("total", estimatedTotal);
                    return result;
                }
                
                // 不过滤状态，使用全部数据
                result.put("list", pageResult.getContent());
                result.put("total", pageResult.getTotalElements());
                return result;
            }
        }
        
        // 处理分页查询结果
        List<Order> orders = pageResult.getContent();
        
        // 如果有状态过滤条件，进行过滤
        if (StringUtils.hasText(status)) {
            orders = orders.stream()
                    .filter(order -> status.equals(order.getStatus()))
                    .collect(Collectors.toList());
        }
        
        result.put("list", orders);
        
        // 计算大致的总数
        double ratio = pageResult.getContent().isEmpty() ? 0 : 
            (double) orders.size() / pageResult.getContent().size();
        long estimatedTotal = (long) (pageResult.getTotalElements() * ratio);
        result.put("total", estimatedTotal);
        
        return result;
    }

    @Override
    @Transactional
    public Order updatePayStatus(Long id, String payStatus) {
        Order order = orderRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("订单不存在"));
        
        order.setPayStatus(payStatus);
        order.setUpdateTime(LocalDateTime.now());
        
        return orderRepository.save(order);
    }

    @Override
    @Transactional
    public Order updatePayStatusWithCoupon(Long id, String payStatus, Long couponId) {
        Order order = orderRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("订单不存在"));
        
        // 更新订单支付状态
        order.setPayStatus(payStatus);
        
        // 支付成功时，保持订单状态为normal（因为用户尚未使用）
        if ("paid".equals(payStatus) && !"used".equals(order.getStatus())) {
            order.setStatus("normal");
        }
        
        order.setUpdateTime(LocalDateTime.now());
        
        // 如果有红包ID，处理红包
        if (couponId != null) {
            // 使用红包
            try {
                // 根据ID获取红包
                Coupon coupon = couponService.getCouponById(couponId);
                if (coupon != null && "未使用".equals(coupon.getStatus())) {
                    Coupon usedCoupon = couponService.useCoupon(couponId);
                    if (usedCoupon == null) {
                        // 红包使用失败
                        System.out.println("红包使用失败: " + couponId);
                    }
                } else {
                    System.out.println("红包不存在或已使用: " + couponId);
                }
            } catch (Exception e) {
                System.out.println("处理红包异常: " + e.getMessage());
            }
        }
        
        return orderRepository.save(order);
    }

    @Override
    public boolean checkTimeConflict(Long courtId, LocalDateTime startTime, LocalDateTime endTime) {
        List<Order> conflictOrders = orderRepository.findConflictOrders(courtId, startTime, endTime);
        return !conflictOrders.isEmpty();
    }

    @Override
    public List<Order> getOrdersByDate(LocalDate date) {
        return orderRepository.findByDate(date);
    }

    @Override
    public List<Order> getOrdersByStatus(String status) {
        return orderRepository.findByStatus(status);
    }
    
    @Override
    public List<Order> getOrdersByUserIdAndStatus(Long userId, String status) {
        return orderRepository.findByUserIdAndStatus(userId, status);
    }
    
    @Override
    @Transactional
    public boolean markOrderAsUsed(Long id) {
        Optional<Order> orderOpt = orderRepository.findById(id);
        if (orderOpt.isPresent()) {
            Order order = orderOpt.get();
            
            // 检查订单是否已支付，只有已支付的订单才能标记为已使用
            if (!"paid".equals(order.getPayStatus())) {
                throw new RuntimeException("只有已支付的订单才能标记为已使用");
            }
            
            // 将订单状态设置为"used"
            order.setStatus("used");
            order.setUpdateTime(LocalDateTime.now());
            orderRepository.save(order);
            return true;
        }
        return false;
    }
    
    /**
     * 清理过期订单
     * 1. 将过期未支付订单标记为已取消
     * 2. 将过期已支付订单标记为已使用
     */
    @Override
    @Transactional
    public int cleanExpiredOrders() {
        int count = 0;
        LocalDateTime now = LocalDateTime.now();
        
        // 1. 处理过期未支付订单: 结束时间已过，但状态为未支付的订单，标记为已取消
        List<Order> unpaidExpiredOrders = orderRepository.findByPayStatus("unpaid");
        for (Order order : unpaidExpiredOrders) {
            // 如果结束时间已过，且状态为normal(未取消)
            if (order.getEndTime().isBefore(now) && "normal".equals(order.getStatus())) {
                order.setStatus("cancelled");
                order.setUpdateTime(now);
                orderRepository.save(order);
                count++;
            }
        }
        
        // 2. 处理过期已支付订单: 结束时间已过，已支付但未标记为已使用的订单，标记为已使用
        List<Order> paidOrders = orderRepository.findByPayStatus("paid");
        for (Order order : paidOrders) {
            // 如果结束时间已过，且状态为normal(未使用)
            if (order.getEndTime().isBefore(now) && "normal".equals(order.getStatus())) {
                order.setStatus("used");
                order.setUpdateTime(now);
                orderRepository.save(order);
                count++;
            }
        }
        
        return count;
    }
    
    /**
     * 处理余额支付
     * 更新订单状态为已支付，并更新用户余额
     */
    @Override
    @Transactional
    public boolean processBalancePayment(Long orderId, Long userId, String giftBalance, 
                                        String rechargeBalance, Long couponId) {
        try {
            // 查找订单
            Optional<Order> orderOptional = orderRepository.findById(orderId);
            if (!orderOptional.isPresent()) {
                System.out.println("订单不存在: " + orderId);
                return false;
            }
            
            Order order = orderOptional.get();
            
            // 验证订单所属用户
            if (!order.getUserId().equals(userId)) {
                System.out.println("订单不属于该用户: " + userId);
                return false;
            }
            
            // 更新订单状态为已支付
            order.setPayStatus("paid");
            order.setStatus("normal"); // 同时将订单状态设置为未使用
            order.setUpdateTime(LocalDateTime.now());
            
            // 如果有红包ID，处理红包
            if (couponId != null) {
                // 获取并使用红包
                try {
                    // 使用红包
                    Coupon usedCoupon = couponService.useCoupon(couponId);
                    if (usedCoupon == null) {
                        System.out.println("红包使用失败: " + couponId);
                    }
                } catch (Exception e) {
                    System.out.println("处理红包异常: " + e.getMessage());
                }
            }
            
            // 保存订单
            orderRepository.save(order);
            
            // 更新用户余额
            Optional<com.tennis.tennisreservation.entity.User> userOptional = userRepository.findById(userId);
            if (!userOptional.isPresent()) {
                System.out.println("用户不存在: " + userId);
                return false;
            }
            
            com.tennis.tennisreservation.entity.User user = userOptional.get();
            
            // 更新用户的余额
            user.setGiftBalance(new java.math.BigDecimal(giftBalance));
            user.setRechargeBalance(new java.math.BigDecimal(rechargeBalance));
            user.setUpdateTime(LocalDateTime.now());
            
            // 保存用户信息
            userRepository.save(user);
            
            System.out.println("余额支付处理成功 - 订单ID: " + orderId + ", 用户ID: " + userId);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("余额支付处理异常: " + e.getMessage());
            return false;
        }
    }
} 